﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Text;

using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Obsidian.Edm;

namespace Obsidian.Utils
{
    public class JsonUtil
    {

        public static T FromStream<T>(Stream stream)
        {
            JsonSerializer serializer = new JsonSerializer();
            T o;
            using (StreamReader streamReader = new StreamReader(stream))
            {
                o = (T)serializer.Deserialize(streamReader, typeof(T));
            }
            return o;
        }

        public static T FromString<T>(String json)
        {
            T o;
            using (MemoryStream stream = new MemoryStream(System.Text.Encoding.Default.GetBytes(json)))
            {
                o = FromStream<T>(stream);
            }
            return o;
        }

        public static T FromFile<T>(String fileName)
        {
            T o;
            using (FileStream fileStream = new FileStream(fileName, FileMode.Open))
            {
                o = FromStream<T>(fileStream);
            }
            return o;
        }

        public static void SetToModel(JObject jo, IModel model)
        {
            IEnumerable<JProperty> props = jo.Properties();
            foreach (JProperty prop in props)
            {
                string propName = prop.Name;
                IModelField field = model.GetFieldByAlias(propName);
                if (field == null)
                    continue;

                object val;
                if (!TryGetValue(jo, propName, out val))
                    continue;

                field.Set(val);
            }
        }

        public static bool TryGetValue(JObject jo, string key, out object val)
        {
            JValue jv;
            if (!TryGetJValue(jo, key, out jv))
            {
                val = null;
                return false;
            }
            val = jv.Value;
            return true;
        }

        public static bool TryGetJValue(JObject jo, string key, out JValue jv)
        {
            JToken jt = jo[key];
            if (jt == null)
            {
                jv = null;
                return false;
            }
            try
            {
                jv = (JValue)jt;
                return true;
            }
            catch (Exception ex)
            {
                jv = null;
                return false;
            }
        }


    }
}
